/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.nageoffer.shortlink.admin.config;

import com.nageoffer.shortlink.admin.common.biz.user.UserFlowRiskControlFilter;
import com.nageoffer.shortlink.admin.common.biz.user.UserTransmitFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;

/**
 * 用户配置自动装配
 */
@Configuration
public class UserConfiguration {

    /**
     * 用户信息传递过滤器
     *
     * 此方法配置了一个过滤器，用于全局范围内拦截HTTP请求，以实现用户信息的传递
     * 它主要目的是在请求处理前，将用户信息（如用户ID、角色等）添加到请求属性中，
     * 以便后端服务可以方便地获取这些信息，进行权限控制、日志记录等操作
     *
     * @return FilterRegistrationBean<UserTransmitFilter> 返回一个过滤器注册对象，包含过滤器实例、URL模式和优先级等信息
     */
    @Bean
    public FilterRegistrationBean<UserTransmitFilter> globalUserTransmitFilter() {
        // 创建一个过滤器注册对象
        FilterRegistrationBean<UserTransmitFilter> registration = new FilterRegistrationBean<>();
        // 设置过滤器实例
        registration.setFilter(new UserTransmitFilter());
        // 添加URL模式，使此过滤器应用于所有请求
        registration.addUrlPatterns("/*");
        // 设置过滤器的优先级为最高，确保它在其他过滤器之前执行
        registration.setOrder(0);
        // 返回过滤器注册对象
        return registration;
    }

    /**
     * 用户操作流量风控过滤器
     *
     * 该方法创建并配置了一个用户操作流量风控过滤器，用于限制用户操作的流量，防止系统过载
     * 它基于Redis实现计数功能，并根据用户配置的限流规则决定是否放行请求
     *
     * @param stringRedisTemplate 用于操作Redis的数据模板，提供字符串类型的读写方法
     * @param userFlowRiskControlConfiguration 用户流量风控配置，包含限流规则和其他配置参数
     * @return 返回一个FilterRegistrationBean对象，其中封装了用户操作流量风控过滤器的实例
     */
    @Bean
    @ConditionalOnProperty(name = "short-link.flow-limit.enable", havingValue = "true")
    public FilterRegistrationBean<UserFlowRiskControlFilter> globalUserFlowRiskControlFilter(
            StringRedisTemplate stringRedisTemplate,
            UserFlowRiskControlConfiguration userFlowRiskControlConfiguration) {
        // 创建FilterRegistrationBean对象，用于注册过滤器
        FilterRegistrationBean<UserFlowRiskControlFilter> registration = new FilterRegistrationBean<>();
        // 设置过滤器实例，传入必要的参数
        registration.setFilter(new UserFlowRiskControlFilter(stringRedisTemplate, userFlowRiskControlConfiguration));
        // 添加过滤器的URL模式，这里对所有请求进行拦截
        registration.addUrlPatterns("/*");
        // 设置过滤器的执行顺序，数字越小优先级越高
        registration.setOrder(10);
        // 返回配置好的FilterRegistrationBean对象
        return registration;
    }
}